package com.zz.framework.core.utils

import android.annotation.SuppressLint
import android.app.Activity
import android.media.AudioFormat
import android.media.AudioRecord
import android.media.MediaRecorder
import android.os.Environment
import com.hjq.permissions.OnPermissionCallback
import com.hjq.permissions.Permission
import com.hjq.permissions.XXPermissions
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import java.io.File
import java.io.FileOutputStream

/**
 * Copyright © 2025 zhun All rights reserved.
 * Created by ZhaoZhun on 2025/4/1 13:29.
 * @author: ZhaoZhun 1820022519@qq.com
 * @version: V1.0
 */
class NoiseFilteredRecorder {
    private var isRecording = false
    private var currentFilePath: String = ""
    private var recordingJob: Job? = null
    private val localFolderPath: String
        get() {
            val rootDir = Environment.getExternalStorageDirectory().getPath() + "/" + Environment.DIRECTORY_DOWNLOADS
            val file = File(rootDir, "hhCache/recordVoice")
            if (!file.exists()) {
                file.mkdirs()
            }
            return file.getAbsolutePath()
        }

    fun startRecording() {
        ActivityStackManager.instance.topActivity?.let {
            XXPermissions.with(it)
                .permission(Permission.RECORD_AUDIO)
                .request(object : OnPermissionCallback {
                    @SuppressLint("MissingPermission")
                    override fun onGranted(permissions: List<String?>, allGranted: Boolean) {
                        if (isRecording) return
                        isRecording = true
                        // 生成新的文件路径（带时间戳）
                        currentFilePath =  localFolderPath + "/" + "voice_" + System.currentTimeMillis() + ".mp3"
                        val audioRecord = AudioRecord(
                            MediaRecorder.AudioSource.MIC,
                            44100,
                            AudioFormat.CHANNEL_IN_MONO,
                            AudioFormat.ENCODING_PCM_16BIT,
                            2048
                        )

                        val pcmFile = File(currentFilePath!!)
                        val fos = FileOutputStream(pcmFile)

                        audioRecord.startRecording()

                        recordingJob = CoroutineScope(Dispatchers.IO).launch {
                            val buffer = ShortArray(2048)

                            while (isRecording) {
                                val readSize = audioRecord.read(buffer, 0, buffer.size)
                                if (readSize > 0 && !isSilent(buffer)) {
                                    fos.write(shortArrayToByteArray(buffer, readSize))
                                }
                            }

                            audioRecord.stop()
                            audioRecord.release()
                            fos.close()
                        }
                    }
                })
        }
    }

    fun stopRecording(): String {
        isRecording = false
        recordingJob?.cancel()
        return currentFilePath // 返回录音文件路径，方便后续播放
    }

    private fun isSilent(buffer: ShortArray): Boolean {
        val rms = Math.sqrt(buffer.map { it * it.toDouble() }.average())
        return rms < 1000 // 静音阈值
    }

    private fun shortArrayToByteArray(shortArray: ShortArray, size: Int): ByteArray {
        val byteArray = ByteArray(size * 2)
        for (i in 0 until size) {
            byteArray[i * 2] = (shortArray[i].toInt() and 0xFF).toByte()
            byteArray[i * 2 + 1] = (shortArray[i].toInt() shr 8 and 0xFF).toByte()
        }
        return byteArray
    }
}